0%

Practical Vim 读书笔记

刚工作的时候,看了王垠的一篇《编辑器之神和神之编辑器》,便落入了使用vim的深坑。工作了那么多年发现每个一段时间重新看vim东西总能学到新的知识,最近快速读完了《Practical Vim》,在这里把一些以前没注意的小技巧再重新整理一下。

normal mode

  • R进入逐字替换
  • f{char}搜索某个字符(比如c),按;可以跳到下一个c位置,按,跳到上一个c
  • 使用相对行号时,如何删除当前行开始向下数3行的内容? d3j
  • q/ 查看使用/搜索过的历史命令
  • q: 查看 ex 命令历史
  • m{char} 标记位置,`{char} 调整到标记位置,其中{char}小写字母是文件内标记,用大写字母是全局标记(可以在文件之间跳转)
  • 0(数字0)是复制专用寄存器,只有y命令会覆盖它,使用y命令后,”0p可以黏贴寄存器内容。覆盖无名寄存器的操作(x,c,d等)不会覆盖0寄存器

insert mode

  • <C-r>{register} 直接输出寄存器的值,比如<C-r>a是输出a寄存器内容
  • <C-r>=6*35<CR> 使用表达式寄存器=,计算6*35的值并输出

virtual mode

  • v高亮选择文本,gv重选上次高亮选区
  • 高亮选中文本后,按o可以将光标在高亮文本起始末尾跳转,方便调整高亮文本

Ex command mode

  • [range] m {address} 把[range] 范围的文本移动到{address}
  • [range] t {address} 把[range] 范围的文本复制到{address}
  • <C-r>{register} 在命令行黏贴寄存器内容
  • [range] normal {command} 使用命令行执行普通模式命令,如 % normal A; 会在所有行后面追加字符;
  • 重复上一次执行的Ex 命令,使用 @:
  • <C-d> 显示可用命令列表,Tab补全命令
  • <C-r><C-w>插入当前光标下的单词到编辑的command中

[range] 范围语法支持:

符号 地址
1 文本第一行
$ 文本的最后一行
0 虚拟行,位于文本第一行上方
. 光标所在行
‘m 位置标记m所在行
‘< 高亮选区的起始行
‘> 高亮选区的结束行
% 整个文件
  1. 允许使用+{number}-{number}对[range]进行偏移
  2. [range] 也支持使用模式匹配

Macro (宏)

录制宏:

  1. q{register} 开启录制
  2. 录入宏的内容
  3. q结束录制

调用宏:@{register}
批量调用: n@{register} ,这里n是执行宏的次数
向录制好的宏追加内容: 用 q{register大写} 开始录制,录制后的内容会追加到原来的宏后面。比如原来用 qa 录制了 dwi 操作,想要再后面加j,可以:

  1. qA 开启宏a的追加
  2. 录制j
  3. q结束录制
  4. 此时@a执行的操作就是dwij

编辑宏:
宏用的寄存器和复制黏贴的寄存器是一样的,需要编辑好录制的宏,可以先将寄存器输出,编辑后复制到寄存器中,继续用@{register}执行宏。比如原来寄存器a录制的宏是dwij,现在想要改成dwi2j,可以:

  1. 在normal mode下,”ap 黏贴出宏内容 dwij
  2. 将内容改成 dwi2j
  3. 选中文本,y”a 覆盖寄存器a内容
  4. 再执行@a,操作就是 dwi2j了

Pattern 模式匹配

vim 的 search(搜索),substitute(替换)命令都支持Pattern,也就是正则表达式匹配
默认情况下,/ 搜索模式的正则表达式,正则表达式的元字符 .*()等,都需要加\转义,也就是在默认情况下/.*搜索的是 .*字符串,而不是任意个字符

magic:
在搜索表达式前加\m使用magic功能,除了 $.*^之外的元字符要加反斜杠,如\m.*搜索的就是任意字符,若不是.*字符串

very magic:
在搜索表达式前\v使用very magic 功能,正则表达式任何元字符都不用加\,如:/\v(a.c){3}$ 就是查找行尾三个字符是a{char}c的表表达式(如abc,acc,aec)。

强制关闭magic:
如果已经set magic,要在搜索表达式里强制不用magic,就在前面加\V,比如已经开启了set magic,使用 /\V.*搜索的是.*字符串。

单词界定:
在very magic 模式下,使用<word>可以以单词为界匹配字符,而不会匹配到其他内容。比如目前有个文本:

1
2
3
4
abc aa
abcdedf
1234
123abc

/\v<abc>搜索时,只有第一行 abc 匹配,123abc不会匹配。

模式匹配边界:
一个匹配的边界通常对应于一个模式的起始与结尾。但我们可以使用元字符 \zs\ze对匹配进行裁剪,使其成为这个完整模式的一个子集(参见 :h /\zs ) 。元 字符 \zs标志着一个匹配的起始,而元字符\ze则用来界定匹配的结束。将二者相结合,我们可以定义一个特殊的模式,它们可以让我们定义一个模式匹配一个较大的文本范围,然后再收窄匹配范围。与单词定界符类似,\zs\ze 均为零宽度元字符。

vim中模式的特殊元字符 ,\zs\ze关键字示例:

必须转义的情况:

  1. 正向查找时,/必须转义。
  2. 反向查找时,?必须转义。
  3. 每次都要转义\

查找&替换
显示当前查找关键词个数: :%s///gn

将光标定位到匹配结果词尾:/lang/e

重用上次查找的模式
:%s/\va.c/123/g
等价于以下两个命令

1
2
/\v.c
%s//123/g

global 命令

:global命令的广义形式如下所示:
:g/{pattern}/[range][cmd]
:g/{re}/{cmd} 在匹配的行上执行命令,如 :g/re/d ,删除包含re字符的行
:v/{re}/{cmd} 在非匹配的行上执行命令 如 :v/re/d ,删除不包含re字符的行